using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace T.FAS.Runtime.ScheduleJob.SPI
{
    /// <summary>
    /// An implementation of <see cref="IDictionary" /> that wraps another <see cref="IDictionary" />
    /// and flags itself 'dirty' when it is modified, enforces that all keys are
    /// strings. 
    ///  </summary>
    [Serializable]    
    public class StringKeyDirtyFlagMap : DirtyFlagMap
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="StringKeyDirtyFlagMap"/> class.
        /// </summary>
        public StringKeyDirtyFlagMap()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="StringKeyDirtyFlagMap"/> class.
        /// </summary>
        /// <param name="initialCapacity">The initial capacity.</param>
        public StringKeyDirtyFlagMap(int initialCapacity)
            : base(initialCapacity)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="StringKeyDirtyFlagMap"/> class.
        /// </summary>
        /// <param name="initialCapacity">The initial capacity.</param>
        /// <param name="loadFactor">The load factor.</param>
        public StringKeyDirtyFlagMap(int initialCapacity, float loadFactor)
            : base(initialCapacity, loadFactor)
        {
        }

        /// <summary>
        /// Gets the keys.
        /// </summary>
        /// <returns></returns>
        public virtual string[] GetKeys()
        {
            return (string[])new ArrayList(KeySet()).ToArray(typeof(string));
        }

        /// <summary>
        /// Adds the name-value pairs in the given <see cref="IDictionary" /> to the <see cref="TaskDataMap" />.
        /// <p>
        /// All keys must be <see cref="String" />s, and all values must be serializable.
        /// </p>
        /// </summary>
        public override void PutAll(IDictionary map)
        {
            IEnumerator itr = new HashSet(map.Keys).GetEnumerator();
            while (itr.MoveNext())
            {
                object key = itr.Current;
                object val = map[key];

                Put(key, val);
                // will throw ArgumentException if value not serializable
            }
        }

        /// <summary>
        /// Adds the given <see cref="int" /> value to the <see cref="ITask" />'s
        /// data map.
        /// </summary>
        public virtual void Put(string key, int value)
        {
            base.Put(key, value);
        }

        /// <summary>
        /// Adds the given <see cref="long" /> value to the <see cref="ITask" />'s
        /// data map.
        /// </summary>
        public virtual void Put(string key, long value)
        {
            base.Put(key, value);
        }

        /// <summary>
        /// Adds the given <see cref="float" /> value to the <see cref="ITask" />'s
        /// data map.
        /// </summary>
        public virtual void Put(string key, float value)
        {
            base.Put(key, value);
        }

        /// <summary>
        /// Adds the given <see cref="double" /> value to the <see cref="ITask" />'s
        /// data map.
        /// </summary>
        public virtual void Put(string key, double value)
        {
            base.Put(key, value);
        }

        /// <summary> 
        /// Adds the given <see cref="bool" /> value to the <see cref="ITask" />'s
        /// data map.
        /// </summary>
        public virtual void Put(string key, bool value)
        {
            base.Put(key, value);
        }

        /// <summary>
        /// Adds the given <see cref="char" /> value to the <see cref="ITask" />'s
        /// data map.
        /// </summary>
        public virtual void Put(string key, char value)
        {
            base.Put(key, value);
        }

        /// <summary>
        /// Adds the given <see cref="String" /> value to the <see cref="ITask" />'s
        /// data map.
        /// </summary>
        public virtual void Put(string key, string value)
        {
            base.Put(key, value);
        }

        /// <summary>
        /// Adds the given serializable object value to the <see cref="TaskDataMap" />.
        /// </summary>
        public override object Put(object key, object value)
        {
            if (!(key is string))
            {

/* Unmerged change from project 'T.FAS.Runtime.ScheduleJob.SPI (net451)'
Before:
                throw new ArgumentException(CommonStringClassSPI.StringKeyDirtyFlagMap_Put);
After:
                throw new ArgumentException(SPI.StringKeyDirtyFlagMap_Put);
*/
                throw new ArgumentException(CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_Put);
            }
            return base.Put(key, value);
        }

        /// <summary> 
        /// Retrieve the identified <see cref="int" /> value from the <see cref="TaskDataMap" />.
        /// </summary>
        public virtual int GetInt(string key)
        {
            object obj = this[key];

            try
            {
                return Convert.ToInt32(obj);
            }
            catch (Exception)
            {

/* Unmerged change from project 'T.FAS.Runtime.ScheduleJob.SPI (net451)'
Before:
                throw new InvalidCastException(CommonStringClassSPI.StringKeyDirtyFlagMap_GetInt);
After:
                throw new InvalidCastException(SPI.StringKeyDirtyFlagMap_GetInt);
*/
                throw new InvalidCastException(CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetInt);
            }
        }

        /// <summary>
        /// Retrieve the identified <see cref="long" /> value from the <see cref="TaskDataMap" />.
        /// </summary>
        public virtual long GetLong(string key)
        {
            object obj = this[key];

            try
            {
                return Convert.ToInt64(obj);
            }
            catch (Exception)
            {

/* Unmerged change from project 'T.FAS.Runtime.ScheduleJob.SPI (net451)'
Before:
                throw new InvalidCastException(CommonStringClassSPI.StringKeyDirtyFlagMap_GetLong);
After:
                throw new InvalidCastException(SPI.StringKeyDirtyFlagMap_GetLong);
*/
                throw new InvalidCastException(CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetLong);
            }
        }

        /// <summary>
        /// Retrieve the identified <see cref="float" /> value from the <see cref="TaskDataMap" />.
        /// </summary>
        public virtual float GetFloat(string key)
        {
            object obj = this[key];

            try
            {
                return Convert.ToSingle(obj);
            }
            catch (Exception)
            {

/* Unmerged change from project 'T.FAS.Runtime.ScheduleJob.SPI (net451)'
Before:
                throw new InvalidCastException(CommonStringClassSPI.StringKeyDirtyFlagMap_GetFloat);
After:
                throw new InvalidCastException(SPI.StringKeyDirtyFlagMap_GetFloat);
*/
                throw new InvalidCastException(CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetFloat);
            }
        }

        /// <summary>
        /// Retrieve the identified <see cref="double" /> value from the <see cref="TaskDataMap" />.
        /// </summary>
        public virtual double GetDouble(string key)
        {
            object obj = this[key];

            try
            {
                return Convert.ToDouble(obj);
            }
            catch (Exception)
            {

/* Unmerged change from project 'T.FAS.Runtime.ScheduleJob.SPI (net451)'
Before:
                throw new InvalidCastException(CommonStringClassSPI.StringKeyDirtyFlagMap_GetDouble);
After:
                throw new InvalidCastException(SPI.CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetDouble);
*/
                throw new InvalidCastException(CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetDouble);
            }
        }

        /// <summary> 
        /// Retrieve the identified <see cref="bool" /> value from the <see cref="TaskDataMap" />.
        /// </summary>
        public virtual bool GetBoolean(string key)
        {
            object obj = this[key];

            try
            {
                return Convert.ToBoolean(obj);
            }
            catch (Exception)
            {

/* Unmerged change from project 'T.FAS.Runtime.ScheduleJob.SPI (net451)'
Before:
                throw new InvalidCastException(CommonStringClassSPI.StringKeyDirtyFlagMap_GetBoolean);
After:
                throw new InvalidCastException(SPI.CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetBoolean);
*/
                throw new InvalidCastException(CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetBoolean);
            }
        }

        /// <summary>
        /// Retrieve the identified <see cref="char" /> value from the <see cref="TaskDataMap" />. 
        /// </summary>
        public virtual char GetChar(string key)
        {
            object obj = this[key];

            try
            {
                return Convert.ToChar(obj);
            }
            catch (Exception)
            {

/* Unmerged change from project 'T.FAS.Runtime.ScheduleJob.SPI (net451)'
Before:
                throw new InvalidCastException(CommonStringClassSPI.StringKeyDirtyFlagMap_GetChar);
After:
                throw new InvalidCastException(SPI.CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetChar);
*/
                throw new InvalidCastException(CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetChar);
            }
        }

        /// <summary>
        /// Retrieve the identified <see cref="String" /> value from the <see cref="TaskDataMap" />.
        /// </summary>
        public virtual string GetString(string key)
        {
            object obj = this[key];

            try
            {
                return (string)obj;
            }
            catch (Exception)
            {

/* Unmerged change from project 'T.FAS.Runtime.ScheduleJob.SPI (net451)'
Before:
                throw new InvalidCastException(CommonStringClassSPI.StringKeyDirtyFlagMap_GetString);
After:
                throw new InvalidCastException(SPI.CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetString);
*/
                throw new InvalidCastException(CommonStringClassDonotTranslated.StringKeyDirtyFlagMap_GetString);
            }
        }
    }
}
